import os

from docx import Document
import matplotlib.pyplot as plt

"""
@FileName：SCL.py
@Description：
    90项症状清单（SCL90）报告：数据统计与分析
@Author：HeYiQing
@Time：2024/5/6 20:00
"""


# 获取个人基本信息的姓名(name)
def get_name(tables):
    # 个人基本信息
    info_table = tables[0]
    name = info_table.cell(0, 3).text
    return name


def get_P(tables):
    # 个人基本信息
    info_table = tables[1]
    try:
        P = int(info_table.cell(13, 1).text)
    except Exception:
        P = 0
    return P


def get_P_avg(tables):
    # 个人基本信息
    info_table = tables[1]
    try:
        P_avg = float(info_table.cell(14, 1).text)
    except Exception:
        P_avg = 0.00
    return P_avg


# 0 原始分(Original score) 1 均分(Average score) 2 参考诊断(Reference diagnosis) 3 均分±标准差(Standard deviation)
# 获取测验结果
def get_test_data(tables, row):
    data_table = tables[1]
    score_list = []
    for item in range(1, 5):
        score_list.append(data_table.cell(row, item).text)
    return score_list


# 获取文件中所有表格
def get_tables(path, file_name):
    abs_file_path = os.path.join(path, file_name)
    file = Document(abs_file_path)
    tables = file.tables
    return tables


# 获取文件中段落
def get_paragraphs(path, file_name):
    abs_file_path = os.path.join(path, file_name)
    file = Document(abs_file_path)
    paragraphs = file.paragraphs
    return paragraphs[14:31]


# 绘制折线图
def plot(x, y, title, x_label, y_label):
    # 正确显示负号
    plt.rcParams['axes.unicode_minus'] = False
    # 使用黑体字体显示中文
    plt.rcParams['font.sans-serif'] = ['SimHei']
    # 创建图表和轴
    plt.figure(figsize=(18, 12))
    # 为了在x轴上使用字符串，我们需要一个索引列表
    indices = range(len(x))
    # 绘制折线图
    plt.plot(x, y, marker='o')
    # 设置x轴的标签为姓名
    plt.xticks(indices, x, rotation=45)
    # 添加标题和轴标签
    plt.title(title, fontsize=24)
    plt.xlabel(x_label, fontsize=24)
    plt.ylabel(y_label, fontsize=24)
    # 显示图形
    plt.grid(True)
    # 保存文件
    path = "F:/比赛/数学建模/24/repo/SCL/阳性/折线图/" + title + ".png"
    directory = os.path.dirname(path)
    if not os.path.exists(directory):
        os.makedirs(directory)
    plt.savefig(path)
    # 显示图表
    # plt.show()
    # 关闭
    plt.close()


def polt_norm(norm_list, tester_list):
    # 正确显示负号
    plt.rcParams['axes.unicode_minus'] = False
    # 使用黑体字体显示中文
    plt.rcParams['font.sans-serif'] = ['SimHei']
    # 创建图表和轴
    plt.figure(figsize=(18, 12))
    # 为了在x轴上使用字符串，我们需要一个索引列表
    indices = range(len(norm_list))
    # 创建一个颜色映射（colormap），以便为每个系列分配不同的颜色
    colors = []
    step = int(256 / 11)
    for r in range(0, 256, step):
        for g in range(0, 256, step):
            for b in range(0, 256, step):
                colors.append((r / 255, g / 255, b / 255))
                if len(colors) >= 110:
                    break
            if len(colors) >= 110:
                break
        if len(colors) >= 110:
            break
    # 绘制折线图
    for i, y in enumerate(tester_list):
        plt.plot(norm_list, y, color=colors[i], marker='o', label=f'系列 {i + 1}')
    # 设置x轴的标签为姓名
    plt.xticks(indices, norm_list, rotation=45)
    # 添加标题和轴标签
    plt.title('SCL-168-测试结果', fontsize=24)
    plt.xlabel('姓名', fontsize=24)
    plt.ylabel('测试结果', fontsize=24)
    # 显示图形
    plt.grid(True)
    # 保存文件
    path = "F:/比赛/数学建模/24/repo/SCL/测试结果/折线图/SCL-168-测试结果.png"
    directory = os.path.dirname(path)
    if not os.path.exists(directory):
        os.makedirs(directory)
    plt.savefig(path)
    # 显示图表
    plt.show()
    # 关闭
    plt.close()


# 完成任务1
def task_01(name_list_A, name_list_B, data_list_A, data_list_B, name):
    # 折线图 start
    x_label = "姓名"
    y_label_ori_A = name + "-原始分"
    y_label_avg_A = name + "-均分"
    y_label_ref_A = name + "-参考诊断"
    y_label_dev_A = name + "-标准差"
    title_ori_A = "SCL-A-" + name + "-原始分-姓名"
    title_avg_A = "SCL-A-" + name + "-均分-姓名"
    title_ref_A = "SCL-A-" + name + "-参考诊断-姓名"
    title_dev_A = "SCL-A-" + name + "-标准差-姓名"
    # 将soma_list每个元素的第一个元素：原始分(Original score)
    ori_score_A = []
    avg_score_A = []
    ref_dia_A = []
    sta_dev_A = []
    for score_list in data_list_A:
        ori_score_A.append(int(score_list[0]))
        avg_score_A.append(float(score_list[1]))
        ref_dia_A.append(score_list[2])
        try:
            dev = score_list[3]
            dev = dev[5:9]
        except Exception as e:
            dev = 0.00
        try:
            sta_dev_A.append(float(dev))
        except Exception:
            sta_dev_A.append(0.00)

    plot(x=name_list_A, y=ori_score_A, title=title_ori_A, x_label=x_label, y_label=y_label_ori_A)
    plot(x=name_list_A, y=avg_score_A, title=title_avg_A, x_label=x_label, y_label=y_label_avg_A)
    plot(x=name_list_A, y=ref_dia_A, title=title_ref_A, x_label=x_label, y_label=y_label_ref_A)
    plot(x=name_list_A, y=sta_dev_A, title=title_dev_A, x_label=x_label, y_label=y_label_dev_A)
    # 折线图 end
    # 折线图 start
    y_label_ori_B = name + "-原始分"
    y_label_avg_B = name + "-均分"
    y_label_ref_B = name + "-参考诊断"
    y_label_dev_B = name + "-标准差"
    title_ori_B = "SCL-B-" + name + "-原始分-姓名"
    title_avg_B = "SCL-B-" + name + "-均分-姓名"
    title_ref_B = "SCL-B-" + name + "-参考诊断-姓名"
    title_dev_B = "SCL-B-" + name + "-标准差-姓名"
    # 将soma_list每个元素的第一个元素：原始分(Original score)
    ori_score_B = []
    avg_score_B = []
    ref_dia_B = []
    sta_dev_B = []
    for score_list in data_list_B:
        ori_score_B.append(int(score_list[0]))
        avg_score_B.append(float(score_list[1]))
        ref_dia_B.append(score_list[2])
        try:
            dev = score_list[3]
            dev = dev[5:9]
        except Exception as e:
            dev = 0.00
        try:
            sta_dev_B.append(float(dev))
        except Exception:
            sta_dev_B.append(0.00)

    plot(x=name_list_B, y=ori_score_B, title=title_ori_B, x_label=x_label, y_label=y_label_ori_B)
    plot(x=name_list_B, y=avg_score_B, title=title_avg_B, x_label=x_label, y_label=y_label_avg_B)
    plot(x=name_list_B, y=ref_dia_B, title=title_ref_B, x_label=x_label, y_label=y_label_ref_B)
    plot(x=name_list_B, y=sta_dev_B, title=title_dev_B, x_label=x_label, y_label=y_label_dev_B)
    # 折线图 end


# 获取姓名
name_list_A = []
name_list_B = []


def table_op(SCL_STR, file_dir_A, file_dir_B, file_list_A, file_list_B):
    # 获取SCL表
    file_table_A = []
    file_table_B = []
    for file_name in file_list_A:  #
        if SCL_STR in file_name:
            table_list = get_tables(file_dir_A, file_name)  #
            file_table_A.append(table_list)
    for file_name in file_list_B:  #
        if SCL_STR in file_name:
            table_list = get_tables(file_dir_B, file_name)  #
            file_table_B.append(table_list)
    for tables in file_table_A:
        name_list_A.append(get_name(tables))
    for tables in file_table_B:
        name_list_B.append(get_name(tables))

    # 获取躯体化(soma_score_list)
    # 0 原始分(Original score) 1 均分(Average score) 2 参考诊断(Reference diagnosis) 3 均分±标准差(Standard deviation)
    A_list = []
    B_list = []
    for tables in file_table_A:
        A_list.append(get_test_data(tables, 12))
    for tables in file_table_B:
        B_list.append(get_test_data(tables, 12))

    # 阳性项目数 P
    P_list_A = []
    for tables in file_table_A:
        P_list_A.append(get_P(tables))
    P_list_B = []
    for tables in file_table_B:
        P_list_B.append(get_P(tables))
    # 阳性项目平均分 P_avg
    P_AVG_list_A = []
    for tables in file_table_A:
        P_AVG_list_A.append(get_P_avg(tables))
    P_AVG_list_B = []
    for tables in file_table_B:
        P_AVG_list_B.append(get_P_avg(tables))

    # task_01(name_list_A, name_list_B, A_list, B_list, "总分")
    plot(name_list_A, P_list_A, "SCL-A-阳性项目数-姓名", "姓名", "阳性项目数")
    plot(name_list_B, P_list_B, "SCL-B-阳性项目数-姓名", "姓名", "阳性项目数")
    plot(name_list_A, P_AVG_list_A, "SCL-A-阳性项目平均分-姓名", "姓名", "阳性项目平均分")
    plot(name_list_B, P_AVG_list_B, "SCL-B-阳性项目平均分-姓名", "姓名", "阳性项目平均分")


def paragraphs_op(SCL_STR, file_dir_A, file_dir_B, file_list_A, file_list_B):
    # 获取SCL表
    file_paragraphs_A = []
    file_paragraphs_B = []
    warn_list = []
    for file_name in file_list_A:  #
        if SCL_STR in file_name:
            tables = get_tables(file_dir_A, file_name)
            paragraphs_list = get_paragraphs(file_dir_A, file_name)  #
            file_paragraphs_A.append(paragraphs_list)
            paragraphs = paragraphs_list[::2]
            for run in paragraphs:
                parts = run.text.split('：')
                if len(parts) > 1:
                    result = parts[1].split('。')[0].strip()
                    if result != '无':
                        warn_list.append(get_name(tables))
    for file_name in file_list_B:  #
        if SCL_STR in file_name:
            tables = get_tables(file_dir_B, file_name)
            paragraphs_list = get_paragraphs(file_dir_B, file_name)  #
            file_paragraphs_B.append(paragraphs_list)
            paragraphs = paragraphs_list[::2]
            for run in paragraphs:
                parts = run.text.split('：')
                if len(parts) > 1:
                    result = parts[1].split('。')[0].strip()
                    if result != '无':
                        warn_list.append(get_name(tables))
    score_para_all_A = []
    score_para_all_B = []
    for even_paragraphs in file_paragraphs_A:
        score_para = []
        even_paragraphs = even_paragraphs[::2]
        for run in even_paragraphs:
            parts = run.text.split('：')
            if len(parts) > 1:
                result = parts[1].split('。')[0].strip()
                score_para.append(result)
        if (len(score_para) > 1):
            score_para_all_A.append(score_para)
    for even_paragraphs in file_paragraphs_B:
        score_para = []
        even_paragraphs = even_paragraphs[::2]
        for run in even_paragraphs:
            parts = run.text.split('：')
            if len(parts) > 1:
                result = parts[1].split('。')[0].strip()
                score_para.append(result)
        if (len(score_para) > 1):
            score_para_all_B.append(score_para)
    norm_list = ['躯体化', '强迫症状', '人际关系敏感', '抑郁', '焦虑', '敌对', '恐怖', '偏执', '精神病性']
    tester_list = score_para_all_A + score_para_all_B
    polt_norm(norm_list, tester_list)
    print(set(warn_list))


if __name__ == '__main__':
    SCL_STR = "SCL90"
    file_dir_A = r"E:\code_special\Gitee\Math_C\repo\A组--69名测试者"
    file_dir_B = r"E:\code_special\Gitee\Math_C\repo\B组--79名测试者"
    file_list_A = os.listdir(file_dir_A)
    file_list_B = os.listdir(file_dir_B)
    # 表格操作
    # table_op(SCL_STR, file_dir_A, file_dir_B, file_list_A, file_list_B)
    # 段落操作
    # paragraphs_op(SCL_STR, file_dir_A, file_dir_B, file_list_A, file_list_B)
